from datetime import datetime
from appstoreconnect import Api
from typing import Dict, Optional
import jwt
import time
import requests
from datetime import datetime, timedelta
from utils.logger import logger

class AppStoreConnectService:
    def __init__(self, key_id: str, key_file: str, issuer_id: str, mock_mode: bool = False):
        """
        初始化 App Store Connect 服务
        
        Args:
            key_id: API密钥ID
            key_file: API密钥文件路径
            issuer_id: 发行者ID
            mock_mode: 是否使用模拟数据模式
        """
        logger.info(f"初始化 App Store Connect 服务 (key_id: {key_id}, issuer_id: {issuer_id})")
        self.mock_mode = mock_mode
        self.key_id = key_id
        self.issuer_id = issuer_id
        self.key_file = key_file
        self.token = None
        self.token_expiry = None
        
        if not mock_mode:
            self.api = Api(key_id=key_id,
                         key_file=key_file,
                         issuer_id=issuer_id)

    def _generate_token(self):
        """生成 JWT token"""
        try:
            logger.debug("开始生成 JWT token")
            with open(self.key_file, 'r') as f:
                private_key = f.read()
            
            expiry = datetime.now() + timedelta(minutes=15)
            self.token_expiry = expiry
            
            payload = {
                'iss': self.issuer_id,
                'exp': int(expiry.timestamp()),
                'aud': 'appstoreconnect-v1'
            }
            
            token = jwt.encode(
                payload,
                private_key,
                algorithm='ES256',
                headers={'kid': self.key_id}
            )
            
            logger.debug("JWT token 生成成功")
            return token
        except Exception as e:
            logger.error(f"生成 JWT token 失败: {str(e)}", exc_info=True)
            raise
    
    def _get_token(self):
        """获取有效的 token"""
        if not self.token or not self.token_expiry or datetime.now() >= self.token_expiry:
            logger.debug("需要生成新的 token")
            self.token = self._generate_token()
        return self.token
    
    def _make_request(self, method, endpoint, **kwargs):
        """发送 API 请求"""
        try:
            url = f'https://api.appstoreconnect.apple.com/v1/{endpoint}'
            headers = {
                'Authorization': f'Bearer {self._get_token()}',
                'Content-Type': 'application/json'
            }
            
            logger.debug(f"发送 {method} 请求到 {url}")
            response = requests.request(method, url, headers=headers, **kwargs)
            response.raise_for_status()
            
            logger.debug(f"请求成功，状态码: {response.status_code}")
            return response.json()
        except requests.exceptions.RequestException as e:
            logger.error(f"API 请求失败: {str(e)}", exc_info=True)
            if hasattr(e.response, 'json'):
                logger.error(f"错误详情: {e.response.json()}")
            raise

    def get_app_info(self, bundle_id: str) -> Optional[Dict]:
        """
        获取应用信息
        
        Args:
            bundle_id: 应用的Bundle ID
            
        Returns:
            应用信息字典或None（如果未找到）
        """
        logger.info(f"获取应用信息 (bundle_id: {bundle_id})")
        if self.mock_mode:
            # 返回模拟数据
            return {
                'id': 'mock-app-id',
                'bundle_id': bundle_id,
                'name': 'Mock App',
                'sku': 'MOCK_SKU'
            }

        try:
            apps = self.api.read_apps()
            app = next((app for app in apps if app.bundle_id == bundle_id), None)
            
            if app:
                return {
                    'id': app.id,
                    'bundle_id': app.bundle_id,
                    'name': app.name,
                    'sku': app.sku
                }
            return None
            
        except Exception as e:
            logger.error(f"获取应用信息失败: {str(e)}")
            raise Exception(f"Failed to get app info: {str(e)}")

    def create_new_version(self, bundle_id: str, version_number: str) -> Dict:
        """
        创建新版本
        
        Args:
            bundle_id: 应用的Bundle ID
            version_number: 新版本号
            
        Returns:
            新版本信息字典
        """
        logger.info(f"创建新版本 (bundle_id: {bundle_id}, version_number: {version_number})")
        if self.mock_mode:
            # 返回模拟数据
            return {
                'success': True,
                'version_id': 'mock-version-id',
                'version_number': version_number,
                'platform': 'IOS',
                'app_store_state': 'PREPARE_FOR_SUBMISSION',
                'created_at': datetime.now().isoformat()
            }

        try:
            # 1. 获取app_id
            app_info = self.get_app_info(bundle_id)
            if not app_info:
                raise Exception(f"No app found with bundle ID: {bundle_id}")

            # 2. 创建新版本
            new_version = self.api.create_app_store_version(
                app_id=app_info['id'],
                version_string=version_number,
                platform="IOS",
                release_type="AFTER_APPROVAL"
            )

            return {
                'success': True,
                'version_id': new_version.id,
                'version_number': version_number,
                'platform': new_version.platform,
                'app_store_state': new_version.app_store_state,
                'created_at': datetime.now().isoformat()
            }

        except Exception as e:
            logger.error(f"创建新版本失败: {str(e)}")
            return {
                'success': False,
                'error': str(e)
            }

    def get_version_status(self, version_id: str) -> Dict:
        """
        获取版本状态
        
        Args:
            version_id: App Store版本ID
            
        Returns:
            版本状态信息字典
        """
        logger.info(f"获取版本状态 (version_id: {version_id})")
        if self.mock_mode:
            # 返回模拟数据
            return {
                'success': True,
                'version_id': version_id,
                'version_string': '1.0.0',
                'platform': 'IOS',
                'app_store_state': 'PREPARE_FOR_SUBMISSION',
                'release_type': 'AFTER_APPROVAL'
            }

        try:
            version = self.api.read_app_store_version(version_id)
            return {
                'success': True,
                'version_id': version.id,
                'version_string': version.version_string,
                'platform': version.platform,
                'app_store_state': version.app_store_state,
                'release_type': version.release_type
            }
        except Exception as e:
            logger.error(f"获取版本状态失败: {str(e)}")
            return {
                'success': False,
                'error': str(e)
            }

    def submit_version_for_review(self, version_id: str) -> Dict:
        """
        提交版本审核
        
        Args:
            version_id: App Store版本ID
            
        Returns:
            提交结果字典
        """
        logger.info(f"提交版本审核 (version_id: {version_id})")
        if self.mock_mode:
            # 返回模拟数据
            return {
                'success': True,
                'version_id': version_id,
                'status': 'submitted'
            }

        try:
            result = self.api.submit_app_store_version_for_review(version_id)
            return {
                'success': True,
                'version_id': version_id,
                'status': 'submitted'
            }
        except Exception as e:
            logger.error(f"提交版本审核失败: {str(e)}")
            return {
                'success': False,
                'error': str(e)
            }
